package Server.Expression;

import java.util.Map;
import java.util.Stack;
 

 
 interface Expression<E> {
    public E interpret(Map<String,Expression> variables);
}
 //Xu Ly Toan Tu So Thuc
class Number implements Expression<Double> {
    private Double    number;
    public Number(Double number) { this.number = number; }
    @Override
    public Double interpret(Map<String,Expression> variables)  { return number; }    
}

class Plus implements Expression<Double> {
    Expression leftOperand;
    Expression rightOperand;
    public Plus(Expression left, Expression right) { 
        leftOperand = left; 
        rightOperand = right;
    }
 
    @Override
    public Double  interpret(Map<String,Expression> variables)  { 
        return (Double)leftOperand.interpret(variables) + (Double)rightOperand.interpret(variables);
    }
}
 
class Minus implements Expression<Double> {
    Expression leftOperand;
    Expression rightOperand;
    public Minus(Expression left, Expression right) { 
        leftOperand = left; 
        rightOperand = right;
    }
 
    @Override
    public Double interpret(Map<String,Expression> variables)  { 
        return (Double)leftOperand.interpret(variables) - (Double)rightOperand.interpret(variables);
    }
}
 
class Variable implements Expression<Double> {
    private String name;
    public Variable(String name)       { this.name = name; }
    @Override
    public Double interpret(Map<String,Expression> variables)  { 
        if(null==variables.get(name)) return Double.valueOf(0); //Either return new Number(0).
        return (Double) variables.get(name).interpret(variables); 
    }
}
class Evaluator implements Expression<Double> {
    private Expression syntaxTree;
 
    public Evaluator(String expression) {
        Stack<Expression> expressionStack = new Stack<Expression>();
        for (String token : expression.split(" ")) {
            if  (token.equals("+")) {
                Expression subExpression = new Plus(expressionStack.pop(), expressionStack.pop());
                expressionStack.push( subExpression );
            }
            else if (token.equals("-")) {
                // it's necessary remove first the right operand from the stack
                Expression right = expressionStack.pop();
                // ..and after the left one
                Expression left = expressionStack.pop();
                Expression subExpression = new Minus(left, right);
                expressionStack.push( subExpression );
            }
            else                        
                expressionStack.push( new Variable(token) );
        }
        syntaxTree = expressionStack.pop();
    }
 
    @Override
    public Double   interpret(Map<String,Expression> context) {
        return (Double) syntaxTree.interpret(context);
    }
}
